package com.kun.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.server.HttpServerResponse;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.kun.common.Result;
import com.kun.controller.dto.UpdateUserDto;
import com.kun.controller.dto.UserDto;
import com.kun.entity.User;
import com.kun.mapper.UserMapper;
import com.kun.service.UserServiceImpl;
import com.kun.utils.TokenUtils;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@ResponseBody
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserServiceImpl userService;

    @ApiOperation("登录操作")
    @PostMapping("/toLogin")
    public Result toLogin(@RequestBody UserDto userDto){

        if (StrUtil.isBlankOrUndefined(userDto.getUsername())
                ||StrUtil.isBlankOrUndefined(userDto.getPassword())
                ||userDto==null){
            return Result.fail("400","用户账号密码不能为空");
        }
        return userService.login(userDto);
    }

    @ApiOperation("注册操作")
    @PostMapping("/register")
    public Result toRegister(@RequestBody UserDto userDto){

        if (StrUtil.isBlankOrUndefined(userDto.getUsername())
                ||StrUtil.isBlankOrUndefined(userDto.getPassword())
                ||userDto==null){
            return Result.fail("400","用户账号密码不能为空");
        }
        return userService.register(userDto);
    }

    @ApiOperation("更新用户信息")
    @PostMapping("/updateUser")
    public Result updateUser(@RequestBody UpdateUserDto updateUserDto){

        return userService.updateUser(updateUserDto.getUser(),updateUserDto.getOld_username());
    }


    /**
     * 查询所有用户
     * @return
     */
    @ApiOperation("查询所有用户")
    @GetMapping("/selectAllUsers")
    public Object selectAllUsers(){


        return userService.selectAllUsers();
    }

    /**
     * 新增和更新用户
     * @return
     */
    @ApiOperation("新增和更新用户")
    @PostMapping("/saveUser")
    public Boolean saveUser(@ApiParam("待新增和更新的用户") @RequestBody User user){
        return (userService.saveUser(user)>0)?true:false;
    }

    @ApiOperation("删除用户")
    @GetMapping("/deleteUser/{id}")
    public Boolean deleteUser(@ApiParam("待删除的用户id") @PathVariable("id") Integer id){
        return (userService.deleteUserById(id)>0)?true:false;
    }

    @ApiOperation("批量删除用户")
    @PostMapping("/batchDeleteUsers")
    public Integer batchDeleteUsers(@ApiParam("待删除的用户ids") @RequestBody List<Integer> ids){
        int num=0;
        for (Integer id : ids) {
            if(userService.deleteUserById(id)>0) num++;
        }
        return num;

    }

    @ApiOperation("根据条件查询用户")
    @GetMapping("/queryUser")
    public Map<String,Object> queryUsersByCondition(@ApiParam("当前页码") @RequestParam Integer pageIndex,
                                                    @ApiParam("页容量")  @RequestParam Integer pageSize,
                                                    @ApiParam("用户名") @RequestParam(required = false) String username,
                                                    @ApiParam("用户邮箱") @RequestParam(required = false) String email,
                                                    @ApiParam("用户地址") @RequestParam(required = false) String address){
        HashMap<String, Object> map = new HashMap<>();
        map.put("username",username);
        map.put("email",email);
        map.put("address",address);
        map.put("pageIndex",pageIndex);
        map.put("pageSize",pageSize);
        List<User> data= userService.queryUsersByCondition(map);
        Integer totalNum = userService.calCountByConditions(map).size();
        Map<String,Object> res=new HashMap<>();
        res.put("usersList",data);
        res.put("totalNum",totalNum);
        return res;
    }

    @ApiOperation("导出User表")
    @GetMapping("/exportUsers")
    public Boolean exportUsers(HttpServletResponse response) throws IOException {
//        1. 从数据库中查询所有数据
        List<User> users = userService.selectAllUsers();

//        2. 创建ExcelWriter对象(模仿Hutool),并填入需要写的内容
        ExcelWriter writer = ExcelUtil.getWriter(true);


//        3. 指定别名
        writer.addHeaderAlias("id","用户id");
        writer.addHeaderAlias("username","用户名");
        writer.addHeaderAlias("password","用户密码");
        writer.addHeaderAlias("nickname","昵称");
        writer.addHeaderAlias("phone","电话");
        writer.addHeaderAlias("email","邮箱");
        writer.addHeaderAlias("address","地址");
        writer.addHeaderAlias("create_time","创建时间");
        writer.write(users, true);

//        4. 设置浏览器响应格式(固定)
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        String filename = URLEncoder.encode("user","UTF-8");
        response.setHeader("Content-Disposition","attachment;filename="+filename+".xlsx");


//        5. 通过response获取输出流,在通过writer内容写到输出流中
        ServletOutputStream out = response.getOutputStream();
        writer.flush(out, true);

//        6. 关闭流
        writer.close();
        out.close();
        return true;
    }

    @ApiOperation("导入User表")
    @PostMapping("/importUsers")
    public Boolean importUsers(@RequestParam("file") MultipartFile multipartFile) throws IOException {
//        1. controller参数为MultipartFile对象
//        2. 从对象中获取输入流
        InputStream inputStream = multipartFile.getInputStream();
//        3. 使用Hutool的读文件操作,得到ExcelReader对象,将输入流放入对象中
        ExcelReader reader = ExcelUtil.getReader(inputStream);
//        4. 读取文件(指定实体类的对象),获得List
//                - 使用readAll直接一次性读取
//                - 使用read(1)从第2行开始读取,注意返回的是List(list)类型,即需要指定每一个User
        List<List<Object>> readAll = reader.read(1);

//        5. 将List插入数据库中
        for (List<Object> objects : readAll) {
            User user = new User();
            user.setUsername(""+ objects.get(1));
            user.setPassword(""+ objects.get(2));
            user.setNickname(""+ objects.get(3));
            user.setPhone(""+ objects.get(4));
            user.setEmail(""+ objects.get(5));
            user.setAddress(""+ objects.get(6));
            userService.saveUser(user);
        }

        return true;
    }




}
